﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MigrationTool
{
    public partial class SelectedTable : Form
    {
        [DllImport("user32.dll")]
        public static extern bool ReleaseCapture();
        [DllImport("user32.dll")]
        public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
        public const int WM_SYSCOMMAND = 0x0112;
        public const int LB_RESETCONTENT   =      0x0184;
        public const int LB_SETSEL = 0x0185;
        public const int SC_MOVE = 0xF010;
        public const int HTCAPTION = 0x0002;
        private System.Threading.Timer hideDelay;
        //private bool m_focus;
        public SelectedTable()
        {
            InitializeComponent();
            this.OK.MouseEnter += OnMouseEnter;
            this.listBox1.MouseEnter += OnMouseEnter;
            this.MouseEnter += OnMouseEnter;
            this.label1.MouseEnter += OnMouseEnter;
            this.label2.MouseEnter += OnMouseEnter;
            //this.OK.MouseLeave += OnMouseLeave;
            //this.listBox1.MouseLeave += OnMouseLeave;
            this.MouseLeave += OnMouseLeave;
            this.MouseDown += OnMouseDown;
            this.label1.MouseDown += OnMouseDown;
            this.label2.MouseDown += OnMouseDown;
        }

private void OnMouseDown(object sender, MouseEventArgs e)
{
    ReleaseCapture();
    SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
}



        private void OnMouseEnter(object sender, EventArgs e)
        {
            //base.OnMouseEnter(e);
            (this.Tag as MainForm).StopHide();
            if (hideDelay != null)
            {
                hideDelay.Dispose();
                hideDelay = null; //

            }
            this.InvokeGotFocus(this, e);
        }

        private void OnMouseLeave(object sender, EventArgs e)
        {
            //if (this.m_focus)
            //    return;
            if (hideDelay == null)
            {
                //hideDelay.Dispose();
                //hideDelay = null; //(this.Tag as MainForm).StopHide();
                hideDelay = new System.Threading.Timer(hideSelect, null, 100, Timeout.Infinite); 
            }
 
            //this.InvokeGotFocus(this, e);
        }

        private void hideSelect(object o)
        {
            this.BeginInvoke((TimerCallback)delegate(object state)
            {
                //this.selectedtable.Tag = null;
                (this.Tag as MainForm).StartHide();
                hideDelay.Dispose();
                hideDelay = null;
            }, o);

        }
        /// <summary>
        /// 判断2个List相不相等
        /// 前提是list中不包含重复的内容
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="listA"></param>
        /// <param name="listB"></param>
        /// <returns></returns>
        private bool LazzyListEqual<T>(List<T> listA,List<T> listB)
        {
            if (listA == listB)
                return true;
            if (listA == null)
            {
                if (listB != null)
                    return false;
            }
            else
                if (listB == null)
                    return false;
            if (listA.Count != listB.Count)
                return false;
            foreach(T item in listA)
            {
                if (!listB.Contains(item))
                    return false;
            }
            return true;

             
        }
        /// <summary>
        /// 设置list的数据源
        /// 设置上了return true
        /// 否则return false
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public bool SetListData(List<string> data)
        {
            Func<bool> action = (Func<bool>)delegate()
                {
                    //this.listBox1.Items.Clear();
                    if (LazzyListEqual(this.listBox1.DataSource as List<string>, data))
                        return false;
                    this.listBox1.DataSource = data;
                    int maxd = (from d in data orderby d.Length descending select d.Length).First();
                    this.listBox1.Size = new Size(Math.Max(200,maxd*8),Math.Min(data.Count * (listBox1.ItemHeight + 1), 600));
                    //this.listBox1.Height = ;
                    this.Size = new Size(this.listBox1.Size.Width + 2, 38 + this.listBox1.Size.Height);
                    return true;
                    //this.Update();
                };
            if (this.IsHandleCreated)
            {
                return (bool)this.Invoke(action);
            }
            else

                return action();

        }
        public void SetSelectedItems(List<string> selectedItems)
        {
            for (int i = 0; i < listBox1.Items.Count; i++)
            {
                SendMessage(listBox1.Handle, LB_SETSEL, selectedItems.IndexOf(listBox1.Items[i] as string) >= 0 ? -1 : 0, i);
                //listBox1.SetSelected(i, selectedItems.IndexOf(listBox1.Items[i] as string) >= 0);
            }
        }
        private void OK_Click(object sender, EventArgs e)
        {
            int count = listBox1.SelectedItems.Count;
            if (count == 0)
                return;
            this.Hide();
            string[] selecteditems = new string[listBox1.SelectedItems.Count];
            listBox1.SelectedItems.CopyTo(selecteditems,0);
            
            (this.Tag as MainForm).setTargetTableNames(selecteditems.ToList<string>());
        }



        private void listBox1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && (e.KeyCode == Keys.A || e.KeyCode == Keys.Z))
            {
                bool selected=(e.KeyCode == Keys.A);
                for (int i = 0; i < listBox1.Items.Count; i++)
                {

                    //listBox1.SetSelected(i, selected);
                    SendMessage(listBox1.Handle, LB_SETSEL, selected ? -1 : 0, i);

                }
            }
        }


    }
}
